iT邦幫忙

2021 iThome 鐵人賽

DAY 16
0
DevOps

從煉獄走到天堂的AWS DevOps 工具及應用開發大進擊系列 第 16

躲開Windows地雷使用AWS的Docker讓你上天堂

  • 分享至 

  • xImage
  •  

Container會飛

在AWS ECS上目前有提供EC2 mode, Fargate, ECS Anywhere,分別為EC2執行Docker、Serverless方式去建立Container,以及雲地混合執行Container,主要會以前兩者去作深入探討

EC2 mode

在EC2裡執行Container,並透過ECS agent來確認目前執行的Container狀態

運作方式

由Cluster做instance的管理以及服務功能的調用,Task則可以定義Instance裡需要執行哪種Container以及數量,使用Cluster的Service指派哪個Instance去執行維護Task。主要以Cluster、Service和Task三者來建構出ECS這項服務,所以在撰寫CDK時,就會需要用到這三個相關的API。

先來看Cluster的參數配置

cluster = ecs.Cluster(self, "Cluster", cluster_name="itdemo-cdk", vpc=vpc,
        capacity=ecs.AddCapacityOptions(
            can_containers_access_instance_role=True,
            instance_type=ec2.InstanceType("t3.micro"),
            desired_capacity=1,
            machine_image_type=ecs.MachineImageType.AMAZON_LINUX_2,
            key_name="itdemo",
            block_devices=[block]))

vpc:預設是跨兩個AZ,兩個public & subnet。這邊VPC筆者採用新建立而非預設。
capacity:在ECS的cluster底下註冊有安裝ECS agent和Docker agent的EC2配置。
block_devices:配置EC2的硬碟空間

Cluster裡的參數配置:vpc & block

vpc = ec2.Vpc(self, "vpc", 
        cidr="10.10.0.0/16",
        enable_dns_hostnames=True,
        enable_dns_support=True,
        max_azs=1,
        nat_gateways=0,
        subnet_configuration=[
            ec2.SubnetConfiguration(name="public1",
            subnet_type=ec2.SubnetType.PUBLIC,
            cidr_mask=24)
        ])

block = auto.BlockDevice(device_name="/dev/xvda",
volume=auto.BlockDeviceVolume.ebs(volume_size=30,volume_type=auto.EbsDeviceVolumeType.GP3), mapping_enabled=True)

vpc:建立一個public subnet
block:這裡調用的library跟Day14/15,所用的不太一樣,因為會把EC2註冊到autoscaling group(ASG),會使用到autoscaling這個library,所以需要安裝以及import。其他參數都跟前兩天的雷同
volume_size:這邊最低限制需要填30GB,否則在deploy的時侯會出現error

設定cluster SG的inbound rules

cluster.connections.allow_from_any_ipv4(ec2.Port.all_traffic())

配置TaskDefinition

task1 = ecs.TaskDefinition(self, "task-cdk",
        network_mode=ecs.NetworkMode.BRIDGE, 
        compatibility=ecs.Compatibility.EC2,
        cpu="256",
        memory_mib="512")

network_mode:這邊採用Bridge的方式,透過EC2的網路來訪問Container
compatibility:ECS EC2 mode
cpu:1vcpu = 1024。256 = 0.25vcpu
memory_mib:512MB

Container的設定

task1.add_container("Application",
        memory_limit_mib=128,
        # image=ecs.ContainerImage.from_registry("httpd:2.4"),
        image=ecs.ContainerImage.from_registry("johnson860312/awswebdb")
        # entry_point=["sh", "-c"],
        # command=["/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground\""],
        ).add_port_mappings(ecs.PortMapping(container_port=80, 
        host_port=80, 
        protocol=ecs.Protocol.TCP))  

memory_limit_mib:限制最低的記憶體
image:選擇想要的Container image,這裡將Day4 build好的Container image push到自己的Docker hub中,所以這邊使用同一個Container image
add_port_mappings這邊採用的網路模式是Bridge可以透過EC2的port mapping到Container的port。可以透過EC2 public DNS/IP access Container,如下:
http://<EC2-DNS/IP>:

建立Service

ecs.Ec2Service(self, "Service",
        cluster=cluster,
        task_definition=task1,
        desired_count=1,
        service_name="SVC-CDK",
        ) 

desired_count:執行task的數量

結果

https://ithelp.ithome.com.tw/upload/images/20210930/201401723qr2kSX4Rb.png
https://ithelp.ithome.com.tw/upload/images/20210930/20140172BiVfXQ7Y6U.png

結論

在撰寫CDK的同時,可以熟悉ECS上面的細節以及地雷,更加了解AWS的服務

程式碼

from aws_cdk import core as cdk
from aws_cdk import (
    aws_ec2 as ec2,
    aws_ecs as ecs,
    aws_autoscaling as auto,
    core
)


class EcsTestStack(cdk.Stack):

    def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your stack goes here
        vpc = ec2.Vpc(self, "vpc", 
        cidr="10.10.0.0/16",
        enable_dns_hostnames=True,
        enable_dns_support=True,
        max_azs=1,
        nat_gateways=0,
        subnet_configuration=[
            ec2.SubnetConfiguration(name="public1",
            subnet_type=ec2.SubnetType.PUBLIC,
            cidr_mask=24)
        ])

        block = auto.BlockDevice(device_name="/dev/xvda",
        volume=auto.BlockDeviceVolume.ebs(volume_size=30, volume_type=auto.EbsDeviceVolumeType.GP3),
        mapping_enabled=True)

        cluster = ecs.Cluster(self, "Cluster", cluster_name="itdemo-cdk", vpc=vpc,
        capacity=ecs.AddCapacityOptions(
            can_containers_access_instance_role=True,
            instance_type=ec2.InstanceType("t3.micro"),
            desired_capacity=1,
            machine_image_type=ecs.MachineImageType.AMAZON_LINUX_2,
            key_name="itdemo",
            block_devices=[block]))
        
        cluster.connections.allow_from_any_ipv4(ec2.Port.all_traffic())
        
        task1 = ecs.TaskDefinition(self, "task-cdk",
        network_mode=ecs.NetworkMode.BRIDGE, 
        compatibility=ecs.Compatibility.EC2,
        cpu="256",
        memory_mib="512")
        
        task1.add_container("Application",
        memory_limit_mib=128,
        # image=ecs.ContainerImage.from_registry("httpd:2.4"),
        image=ecs.ContainerImage.from_registry("johnson860312/awswebdb")
        # entry_point=["sh", "-c"],
        # command=["/bin/sh -c \"echo '<html> <head> <title>Amazon ECS Sample App</title> <style>body {margin-top: 40px; background-color: #333;} </style> </head><body> <div style=color:white;text-align:center> <h1>Amazon ECS Sample App</h1> <h2>Congratulations!</h2> <p>Your application is now running on a container in Amazon ECS.</p> </div></body></html>' > /usr/local/apache2/htdocs/index.html && httpd-foreground\""],
        ).add_port_mappings(ecs.PortMapping(container_port=80, 
        host_port=80, 
        protocol=ecs.Protocol.TCP))        

        ecs.Ec2Service(self, "Service",
        cluster=cluster,
        task_definition=task1,
        desired_count=1,
        service_name="SVC-CDK",
        ) 

上一篇
透過寫程式可以更熟悉AWS console上的完整操作
下一篇
Fargate不是發糕不能吃
系列文
從煉獄走到天堂的AWS DevOps 工具及應用開發大進擊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言